package com.yugong.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yugong.common.Const;
import com.yugong.entity.dto.*;
import com.yugong.entity.vo.response.SystemListResponseVO;
import com.yugong.mapper.*;
import com.yugong.service.SystemService;
import com.yugong.util.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 系统业务逻辑实现类
 *
 * @author yugong
 * @date 2024/3/2
 */
@Slf4j
@Service
public class SystemServiceImpl implements SystemService {
    @Resource
    private AccountMapper accountMapper;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private OrderClassMapper orderClassMapper;
    @Resource
    private CourseMapper courseMapper;
    @Resource
    private StudentMapper studentMapper;
    @Resource
    private CourseScoreMapper courseScoreMapper;
    @Resource
    private CourseArrangeMapper courseArrangeMapper;
    @Resource
    private TeacherMapper teacherMapper;
    @Resource
    private RoomMapper roomMapper;
    @Resource
    private CollageMapper collageMapper;
    @Resource
    private OrderClassAdminMapper orderClassAdminMapper;
    @Resource
    private OfficeUtils officeUtils;
    @Resource
    private SystemUtils systemUtils;
    @Resource
    private BrowserUtils browserUtils;
    @Resource
    private TimeUtils timeUtils;
    @Resource
    private DigestUtils digestUtils;


    /**
     * 根据账号导出学生成绩表
     *
     * @param accountNo      账号
     * @param orderClassName 班名
     * @return 是否成功
     */
    @Override
    public boolean exportStudentScoreExcel(String accountNo, String orderClassName) {
        List<Object> studentCourseScoreList = new ArrayList<>();
        List<String> columnList = new ArrayList<>();
        columnList.add("班号");
        columnList.add("班名");
        columnList.add("课程号");
        columnList.add("课程名");
        columnList.add("学号");
        columnList.add("姓名");
        columnList.add("成绩");
        String excelName = "";
        Account account = accountMapper.selectById(accountNo);
        Role role = roleMapper.selectById(account.getAccountRoleNo());
        if (Const.ROLE_COMMON_STUDENT.equals(role.getRoleName()) || Const.ROLE_VISITOR_STUDENT.equals(role.getRoleName())) {
            LambdaQueryWrapper<CourseScore> courseScoreLambdaQueryWrapper = new LambdaQueryWrapper<>();
            courseScoreLambdaQueryWrapper
                    .eq(CourseScore::getCourseScoreStudentNo, accountNo)
                    .orderByDesc(CourseScore::getCourseScoreCreateTime);
            List<CourseScore> courseScoreList = courseScoreMapper.selectList(courseScoreLambdaQueryWrapper);
            for (CourseScore courseScore : courseScoreList) {
                OrderClass orderClass = orderClassMapper.selectById(courseScore.getCourseScoreOrderClassNo());
                studentCourseScoreList.add(orderClass.getOrderClassNo());
                studentCourseScoreList.add(orderClass.getOrderClassName());
                Course course = courseMapper.selectById(courseScore.getCourseScoreCourseNo());
                studentCourseScoreList.add(course.getCourseNo());
                studentCourseScoreList.add(course.getCourseName());
                Student student = studentMapper.selectById(courseScore.getCourseScoreStudentNo());
                studentCourseScoreList.add(student.getStudentNo());
                studentCourseScoreList.add(student.getStudentName());
                studentCourseScoreList.add(courseScore.getCourseScoreAchievement());
                excelName = student.getStudentNo() + "-" + student.getStudentName();
            }
        }
        return officeUtils.exportExcel("", excelName + "成绩表", "", columnList, studentCourseScoreList);
    }


    /**
     * 获取系统参数
     *
     * @param request http请求
     * @return 系统参数
     */
    @Override
    public SystemListResponseVO getSystemParameter(HttpServletRequest request) {
        SystemListResponseVO systemListResponseVO = new SystemListResponseVO();
        systemListResponseVO.setBrowserType(browserUtils.getBrowserType(request));
        systemListResponseVO.setBrowserVersion(browserUtils.getBrowserVersion(request));
        systemListResponseVO.setIpAddress(systemUtils.getIPAddress(request));
        systemListResponseVO.setCpuArch(systemUtils.getCpuArch(request));
        systemListResponseVO.setOsName(systemUtils.getOSName(request));
        systemListResponseVO.setJvmName(systemUtils.getJvmName());
        systemListResponseVO.setJdkVersion(systemUtils.getJdkVersion());
        long jvmStartTime = systemUtils.getJvmStartTime();
        systemListResponseVO.setJvmStartTime(timeUtils.setDateToStrDate(timeUtils.longToDate(jvmStartTime, Const.YYYY_MM_DD_HH_MM_SS), Const.YYYY_MM_DD_HH_MM_SS));
        long jvmUpTime = systemUtils.getJvmUpTime();
        systemListResponseVO.setJvmUpTime(timeUtils.longToHMS(jvmUpTime));
        long heapMemoryInit = systemUtils.getHeapMemoryInit();
        systemListResponseVO.setHeapMemoryInit(timeUtils.longToPercentage(heapMemoryInit));
        long heapMemoryUsed = systemUtils.getHeapMemoryUsed();
        systemListResponseVO.setHeapMemoryUsed(timeUtils.longToPercentage(heapMemoryUsed));
        long heapMemoryCommitted = systemUtils.getHeapMemoryCommitted();
        systemListResponseVO.setHeapMemoryCommitted(timeUtils.longToPercentage(heapMemoryCommitted));
        long nonHeapMemoryInit = systemUtils.getNonHeapMemoryInit();
        systemListResponseVO.setNonHeapMemoryInit(timeUtils.longToPercentage(nonHeapMemoryInit));
        long nonHeapMemoryUsed = systemUtils.getNonHeapMemoryUsed();
        systemListResponseVO.setNonHeapMemoryUsed(timeUtils.longToPercentage(nonHeapMemoryUsed));
        long nonHeapMemoryCommitted = systemUtils.getNonHeapMemoryCommitted();
        systemListResponseVO.setNonHeapMemoryCommitted(timeUtils.longToPercentage(nonHeapMemoryCommitted));
        return systemListResponseVO;
    }

    /**
     * 导入学生Excel文件
     *
     * @param file Excel文件
     * @return 文件名
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String uploadStudentExcel(MultipartFile file) {
        Date createTime = new Date();
        String fileName = file.getOriginalFilename();
        List<String> studentList = null;
        try {
            studentList = officeUtils.importExcel(fileName, file.getInputStream());
        } catch (IOException ioException) {
            log.error("导入学生Excel异常：" + ioException.getMessage(), ioException);
        }
        if (studentList != null) {
            for (int index = 8; index < studentList.size(); index += 8) {
                Account account = new Account();
                account.setAccountNo(studentList.get(index));
                account.setAccountPassword(digestUtils.md5Digest(studentList.get(index + 1)));
                account.setAccountRoleNo(2);
                account.setAccountPhoto(studentList.get(index + 5));
                account.setAccountPhone(digestUtils.base64Encode(studentList.get(index + 6)));
                account.setAccountEmail(digestUtils.base64Encode(studentList.get(index + 7)));
                account.setAccountCreateMan("admin");
                account.setAccountCreateTime(createTime);
                Student student = new Student();
                student.setStudentNo(studentList.get(index));
                student.setStudentName(studentList.get(index + 2));
                student.setStudentAge(Integer.valueOf(studentList.get(index + 3)));
                if ("男".equals(studentList.get(index + 4))) {
                    student.setStudentSex(1);
                } else {
                    student.setStudentSex(0);
                }
                student.setStudentCreateMan("admin");
                student.setStudentCreateTime(createTime);
                accountMapper.insert(account);
                studentMapper.insert(student);
            }
        }
        return fileName;
    }

    /**
     * 导入教师Excel文件
     *
     * @param file Excel文件
     * @return 文件名
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String uploadTeacherExcel(MultipartFile file) {
        Date createTime = new Date();
        String fileName = file.getOriginalFilename();
        List<String> teacherList = null;
        try {
            teacherList = officeUtils.importExcel(fileName, file.getInputStream());
        } catch (IOException ioException) {
            log.error("导入教师Excel异常：" + ioException.getMessage(), ioException);
        }
        if (teacherList != null) {
            for (int index = 11; index < teacherList.size(); index += 11) {
                Account account = new Account();
                account.setAccountNo(teacherList.get(index));
                account.setAccountPassword(digestUtils.md5Digest(teacherList.get(index + 1)));
                account.setAccountRoleNo(3);
                account.setAccountPhoto(teacherList.get(index + 8));
                account.setAccountPhone(digestUtils.base64Encode(teacherList.get(index + 9)));
                account.setAccountEmail(digestUtils.base64Encode(teacherList.get(index + 10)));
                account.setAccountCreateMan("admin");
                account.setAccountCreateTime(createTime);
                Teacher teacher = new Teacher();
                teacher.setTeacherNo(teacherList.get(index));
                teacher.setTeacherName(teacherList.get(index + 2));
                teacher.setTeacherAge(Integer.valueOf(teacherList.get(index + 3)));
                if ("男".equals(teacherList.get(index + 4))) {
                    teacher.setTeacherSex(1);
                } else {
                    teacher.setTeacherSex(0);
                }
                teacher.setTeacherPositionalTitle(teacherList.get(index + 5));
                LambdaQueryWrapper<Collage> collageLambdaQueryWrapper = new LambdaQueryWrapper<>();
                collageLambdaQueryWrapper
                        .eq(Collage::getCollageName, teacherList.get(index + 6));
                Collage collage = collageMapper.selectOne(collageLambdaQueryWrapper);
                if (collage != null) {
                    teacher.setTeacherCollageNo(collage.getCollageNo());
                }
                LambdaQueryWrapper<Room> roomLambdaQueryWrapper = new LambdaQueryWrapper<>();
                roomLambdaQueryWrapper
                        .eq(Room::getRoomName, teacherList.get(index + 7));
                Room room = roomMapper.selectOne(roomLambdaQueryWrapper);
                if (room != null) {
                    teacher.setTeacherRoomNo(room.getRoomNo());
                }
                teacher.setTeacherCreateMan("admin");
                teacher.setTeacherCreateTime(createTime);
                accountMapper.insert(account);
                teacherMapper.insert(teacher);
            }
        }
        return fileName;
    }

    /**
     * 导入订单班管理员Excel文件
     *
     * @param file Excel文件
     * @return 文件名
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String uploadOrderClassAdminExcel(MultipartFile file) {
        Date createTime = new Date();
        String fileName = file.getOriginalFilename();
        List<String> orderClassAdminList = null;
        try {
            orderClassAdminList = officeUtils.importExcel(fileName, file.getInputStream());
        } catch (IOException ioException) {
            log.error("导入订单班管理员Excel异常：" + ioException.getMessage(), ioException);
        }
        if (orderClassAdminList != null) {
            for (int index = 10; index < orderClassAdminList.size(); index += 10) {
                Account account = new Account();
                account.setAccountNo(orderClassAdminList.get(index));
                account.setAccountPassword(digestUtils.md5Digest(orderClassAdminList.get(index + 1)));
                account.setAccountRoleNo(5);
                account.setAccountPhoto(orderClassAdminList.get(index + 7));
                account.setAccountPhone(digestUtils.base64Encode(orderClassAdminList.get(index + 8)));
                account.setAccountEmail(digestUtils.base64Encode(orderClassAdminList.get(index + 9)));
                account.setAccountCreateMan("admin");
                account.setAccountCreateTime(createTime);
                OrderClassAdmin orderClassAdmin = new OrderClassAdmin();
                orderClassAdmin.setOrderClassAdminNo(orderClassAdminList.get(index));
                orderClassAdmin.setOrderClassAdminName(orderClassAdminList.get(index + 2));
                orderClassAdmin.setOrderClassAdminAge(Integer.valueOf(orderClassAdminList.get(index + 3)));
                if ("男".equals(orderClassAdminList.get(index + 4))) {
                    orderClassAdmin.setOrderClassAdminSex(1);
                } else {
                    orderClassAdmin.setOrderClassAdminSex(0);
                }
                LambdaQueryWrapper<Collage> collageLambdaQueryWrapper = new LambdaQueryWrapper<>();
                collageLambdaQueryWrapper
                        .eq(Collage::getCollageName, orderClassAdminList.get(index + 5));
                Collage collage = collageMapper.selectOne(collageLambdaQueryWrapper);
                if (collage != null) {
                    orderClassAdmin.setOrderClassAdminCollageNo(collage.getCollageNo());
                }
                LambdaQueryWrapper<Room> roomLambdaQueryWrapper = new LambdaQueryWrapper<>();
                roomLambdaQueryWrapper
                        .eq(Room::getRoomName, orderClassAdminList.get(index + 6));
                Room room = roomMapper.selectOne(roomLambdaQueryWrapper);
                if (room != null) {
                    orderClassAdmin.setOrderClassAdminRoomNo(room.getRoomNo());
                }
                orderClassAdmin.setOrderClassAdminCreateMan("admin");
                orderClassAdmin.setOrderClassAdminCreateTime(createTime);
                accountMapper.insert(account);
                orderClassAdminMapper.insert(orderClassAdmin);
            }
        }
        return fileName;
    }
}
